package com.xinyue.javaCore.reflect;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Type;

public class ParamToObject {

	//单例模式：私有构造器
	private ParamToObject() {
		
	}
	//单例模式：私有类
	private static class SingletonHolder{  
        private static ParamToObject instance = new ParamToObject();  
    }
	//单利模式创建对象
	public static ParamToObject getInstance() {
		return SingletonHolder.instance;
	}
	
	/**
	 * 传入参数，获取数据对象
	 * @param <T>
	 * @param 字符串参数
	 * @param 对象.class
	 * @return
	 */
	public <T> T fromPararms(String params, Class<T> clazz) {
		
		//利用反射创建class对象
		T target = null;
		
		try {
			target = clazz.newInstance();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
		
		//如果参数不为null或者不等于""则处理
		if(params != null && !"".equals(params)) {
			//切割参数组
			String[] paramGroups = params.split("&");
			
			for(int i = 0; i < paramGroups.length; i++) {
				//有效性验证
				if(isValidParam(paramGroups[i])) {
					String[] param = paramGroups[i].split("=");
					try {
						Field field = clazz.getDeclaredField(param[0]);
						//private类型变量赋值
						field.getModifiers();
						Method m = clazz.getMethod(getSetterMethod(param[0]), new Class[] {field.getType()});
						//方法调用
						m.invoke(target, getValue(param[1], field.getGenericType()));
					} catch (Exception e) {
						e.printStackTrace();
						//TODO System.out.println("error!!ParamToObject.getObject():" + e.getMessage());
					}
				}
			}
		}
		
		return target;
	}
	
	//获得setter方法名
	private String getSetterMethod(String param) {
		return "set" + param.replaceFirst(String.valueOf(param.charAt(0)), String.valueOf((char)(param.charAt(0)-32)));
	}
	
	//判断"key=value"是否是有效数据。去除"=v"、"k="、"="、""
	private boolean isValidParam(String param) {
		
		if("".equals(param)) {
			return false;
		}else if(param.startsWith("=")) {
			return false;
		}else if(param.split("=").length != 2) {
			return false;
		}else {
			return true;
		}
	}
	
	@SuppressWarnings("unchecked")
	private <T> T getValue(String value, Type type) {
		
		if(String.class == type) {
			return (T) value;
		}else if(Integer.TYPE == type) {
			return (T) Integer.valueOf(value);
		}else if(Long.TYPE == type) {
			return (T) Long.valueOf(value);
		}else if(Boolean.TYPE == type) {
			return (T) Boolean.valueOf(value);
		}else if(Double.TYPE == type) {
			return (T) Double.valueOf(value);
		}else if(Float.TYPE == type) {
			return (T) Float.valueOf(value);
		}
		return (T) value;
	}
}
